import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.Before;
import org.junit.After;

 /**
  * @author Irina 
  *This class is for the VendingMachine test cases class
  *   
  */ 

public class VendingMachineTest {
         //Declaring variable of type VendingMachine
         VendingMachine vm;     
        //Declaring variable of type VendingMachineItem 
        VendingMachineItem vmi_item; 

        //creating new instance of VendingMachine and VendingMachineItem before running a test case
        @Before   
        public void setUp() throws Exception { 
 
               vm = new VendingMachine(); 
               vmi_item = new VendingMachineItem("Snickers",1.0);     
    }
         //Tests If you add an item with an invalid code
         @Test (expected=VendingMachineException.class) 
         public void testGetSLotIndex(){     
               vm.addItem(vmi_item,"E");   
               assertEquals(vmi_item,vm.getItem("E")); 
        }      

        //Tests if item add to the vending machine when slot is empty, given a valid code 
        @Test         
        public void testAddItem (){   
              vm.addItem(vmi_item,"A");    
              assertEquals(vmi_item,vm.getItem("A"));   
        }                

        //Tests if item add to the vending machine when slot is empty, given a valid code B 
        @Test       
        public void testAddItem_B (){ 
             vm.addItem(vmi_item,"B");      
             assertEquals(vmi_item,vm.getItem("B"));  
        }                 

        //Tests if item add to the vending machine when slot is empty, given a valid code B
        @Test         
        public void testAddItem_C (){
              vm.addItem(vmi_item,"C");
              assertEquals(vmi_item,vm.getItem("C")); 
        }             

        //Tests if item add to the vending machine when slot is empty, given a valid code C
        @Test     
        public void testAddItem_D (){ 
              vm.addItem(vmi_item,"C"); 
              assertEquals(vmi_item,vm.getItem("C")); 
        }                 

         //Tests If you add an item with an invalid code
         @Test (expected=VendingMachineException.class)
          public void testAddItem_invalidCode (){    
               vm.addItem(vmi_item,"D"); 
               assertEquals(vmi_item,vm.getItem("E"));  
        }    

        //Tests If you add an item to a slot that is already occupied 
        @Test (expected=VendingMachineException.class)         
        public void testAddItem_valid_Multiple (){     
               vm.addItem(vmi_item,"A");            
               vm.addItem(vmi_item,"A");             
               assertEquals(vmi_item,vm.getItem("A"));   
        }                 

        //Tests if removes item from a slot for a given code when slot is not is empty 
        @Test         
        public void testRemoveItem(){   
                vm.addItem(vmi_item,"A");     
                vm.removeItem("A");          
                assertEquals(null,vm.getItem("A")); 
        }            

        //Tests If removes item from a slot given an invalid code 
         @Test (expected=VendingMachineException.class) 
         public void testRemoveItem_invalidCode (){   
                vm.addItem(vmi_item,"A");          
                vm.removeItem("E");               
                assertEquals(null,vm.getItem("E"));  
        }                       

        //Tests If removes item from a slot already empty  
        @Test (expected=VendingMachineException.class)       
        public void testRemoveItem_empty (){
                //adding item to a slot  
                vm.addItem(vmi_item,"A");   
                //removing item from a slot  
                vm.removeItem("A");       
                //removing from a slot that is already empty 
                vm.removeItem("A");  
                assertEquals(null,vm.getItem("A"));  
       }              

       //Tests if it works when a valid amount(greater than zero) is inserted 
       @Test    
       public void testInsertMoney() { 
                vm.insertMoney(1.0); 
                double balance=0.0;   
                balance= balance + 1.0; 
                assertEquals(balance,vm.balance,0);  
       }                  

       //Tests if it works when an invalid amount(less than zero) is inserted 
       @Test (expected=VendingMachineException.class)                  
       public void testInsertMoney_invalid() {              
                vm.insertMoney(-1.0);                 
                assertEquals(-1.0,vm.balance,0);      
       }                  

       //Tests if it works when an amount is equal to zero is inserted   
       @Test 
       public void testInsertMoney_zeroPrice() { 
               vm.insertMoney(0.0);      
               double balance=0.0;     
               balance= balance + 0.0;   
               assertEquals(balance,vm.balance,0);    
       }              

       //Tests if it returns balance in the machine when an amount of money is inserted 
       @Test         
       public void testGetBalance() { 
               vm.insertMoney(1.00);  
               assertEquals( 1.00, vm.getBalance(),0); 
       }               

       //Tests if it works when a valid amount of money is inserted
       @Test                  
       public void testMakePurchase() {
               vm.addItem(vmi_item, "A");
               vm.insertMoney(2.00);     
               assertTrue(vm.makePurchase("A"));  
       }                   

       //Tests if it works when money less than the price is inserted
       @Test                
       public void testMakePurchase_lessMoney() {
               vm.addItem(vmi_item, "A");     
               vm.insertMoney(.50);            
               assertFalse(vm.makePurchase("A"));
       }           
 
       //Tests if it works when money less than the price is inserted
       @Test                  
       public void testMakePurchase_emptySlot() {  
               vm.addItem(vmi_item, "A");       
               vm.removeItem("A");         
               vm.insertMoney(2.00);        
               assertFalse(vm.makePurchase("A")); 
       }          

       //Tests if it returns change with a valid amount of  money 
       @Test                    
       public void testReturnChange() { 
               vm.addItem(vmi_item, "A");   
               vm.insertMoney(2.00); 
               vm.makePurchase("A");  
               assertEquals(1.00, vm.returnChange(),0);  
       }                   
     
       //Tests if it works when there is no change to return 
       @Test                   
       public void testReturnChange_noChange() {  
               vm.addItem(vmi_item, "A");   
               vm.insertMoney(1.00);      
               vm.makePurchase("A");        
               assertEquals(0.00, vm.returnChange(),0);
       }                   

       //Clearing any previous value of vmi_item after a test case completed running 
       @After
       public void tearDown() throws Exception { 
                vm=null;             
    }   
}   


